<?php
class Session {
	public static $options = array(
		'handler' => 'file', 
		'duration' => 1440, 
		'gc_probability' => 1, 
		'gc_divisor' => 1000, 
		'path' => '/', 
		'seed' => ''
	);
	public static $ip;
	public static $agent;

	/* 初始化自己 */
	public static function &singleton(){
		static $instance;
		if(!isset($instance)){
			$instance=new Session();
		}
		return $instance;
	}
	/**
	 * 启用session
	 * SESSION　GC发生的机率，机率的计算公式为gc_probability/gc_divisor
	 * @param array $options 设置选项
	 */
	public function __construct ($options = array(),$force=false) {
		$options = self::$options = array_merge(self::$options, $options);
		$handler = $options['handler'];
		$options['divisor'] = $options['gc_divisor'];
		$session_name = self::name();
	  
		session_start();
		header('P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"'); //为IE6.0安全策略发送修改过的头信息
		ini_set('session.gc_maxlifetime', $options['duration']);
		ini_set('session.gc_probability', $options['gc_probability']);
		ini_set('session.gc_divisor', $options['gc_divisor']);
		self::$ip = self::ip();
		if (isset($_SERVER['HTTP_USER_AGENT'])) self::$agent = $_SERVER['HTTP_USER_AGENT'];
		
		//session_set_cookie_params(0, $options['path']);
		if (! isset($_SESSION['o2php'])) {
			$time = time();
			$_SESSION['o2php'] = array(
				'counter' => 0, 
				'start' => $time, 
				'last' => $time, 
				'now' => $time, 
				'ip' => self::$ip, 
				'agent' => self::$agent
			);
		}
		else {
			$_SESSION['o2php']['counter'] += 1;
			$_SESSION['o2php']['last'] = $_SESSION['o2php']['now'];
			$_SESSION['o2php']['now'] = time();
		}
	}

	/**
	 * 获得客户端IP地址
	 *
	 * @return string
	 */
	function ip () {
		static $ip;
		if (! isset($ip)) {
			$c = getenv('HTTP_CLIENT_IP');
			$x = getenv('HTTP_X_FORWARDED_FOR');
			$r = getenv('REMOTE_ADDR');
			$sr = $_SERVER['REMOTE_ADDR'];
			if ($c && strcasecmp($c, 'unknown')) {
				$ip = $c;
			}
			elseif ($x && strcasecmp($x, 'unknown')) {
				$ip = $x;
			}
			elseif ($r && strcasecmp($r, 'unknown')) {
				$ip = $r;
			}
			elseif ($sr && strcasecmp($sr, 'unknown')) {
				$ip = $sr;
			}
			$ip = preg_match("/^([\d]{1,3}\.){3}[\d]{1,3}$/", $ip) ? $ip : 'unknown';
		}
		return $ip;
	}
	/**
	 * 取session名
	 * 
	 */
	public static function name () {
		$seed = self::$options['seed'];
		return '_' . substr(md5($seed . self::$agent . self::$ip), 0, 9);
	}

	/**
	 * 销毁session
	 * 
	 */
	public static function destroy () {
		//if (isset($_COOKIE[session_name()])) setcookie(session_name(), '', time() - 42000, '/');
		session_unset();
		session_destroy();
	}

	/**
	 * 创建一个新的Token(标志)字符串
	 *
	 * @param int $length 字符串长度
	 * @return string $id 返回token串
	 */
	protected static function token ($length = 32) {
		static $token;
		if (! isset($token)) {
			$chars = '0123456789abcdef';
			$max = strlen($chars) - 1;
			$token = '';
			for ($i = 0; $i < $length; ++ $i)
				$token .= $chars[(rand(0, $max))];
			$token = md5($token . session_name());
		}
		return $token;
	}
}